﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using EnvDTE;
using EnvDTE80;

namespace CTX.CtxPackage
{
    /// <summary>
    /// Interaction logic for MyControl.xaml
    /// </summary>
    public partial class MyControl : UserControl
    {
        public MyControl()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MyControl_Loaded);
        }

        void MyControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (DTE != null && DTE.Solution != null)
            {
                BindProjects();
            }
        }         
        public DTE DTE { get; set; }
        public IServiceProvider ServiceProvider { get; set; }

        public void BindProjects()
        {
            DataContext = new MyControlModel(ServiceProvider,DTE);
        }

        
    }

    public class MyControlModel
    {
        #region Ctor
        public MyControlModel(IServiceProvider serviceProvider, DTE dte)
        {
            DTE = dte;
            ServiceProvider = serviceProvider;
            Projects = GetAllProjects();
            ProjectSelector = new ProjectSelector(ServiceProvider);
            BuildSolutionCommand = new DelegateCommand(OnBuildSolution);
            RebuildSolutionCommand = new DelegateCommand(OnRebuildSolution);
            ClearSolutionCommand = new DelegateCommand(OnClearSolution);
        }
        #endregion

        #region Properties
        public DTE DTE { get; private set; }

        public List<ProjectModel> Projects { get; set; }

        protected ProjectSelector ProjectSelector { get; private set; }

        protected IServiceProvider ServiceProvider { get; private set; }
        #endregion

        #region Commands
        public ICommand BuildSolutionCommand { get; set; }
        public void OnBuildSolution(object parameter)
        {
            try
            {
                var solutionBuild2 = (SolutionBuild2)DTE.Solution.SolutionBuild;
                solutionBuild2.Build(true);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        public ICommand RebuildSolutionCommand { get; set; }
        public void OnRebuildSolution(object parameter)
        {
            try
            {
                var solutionBuild2 = (SolutionBuild2)DTE.Solution.SolutionBuild;
                solutionBuild2.Clean(true);
                solutionBuild2.Build(true);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        public ICommand ClearSolutionCommand { get; set; }
        public void OnClearSolution(object parameter)
        {
            try
            {
                var solutionBuild2 = (SolutionBuild2)DTE.Solution.SolutionBuild;
                solutionBuild2.Clean(true);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        #endregion

        #region Helper Methods
        private List<ProjectModel> GetAllProjects()
        {
            var solution2 = (Solution2)DTE.Solution;
            var solution2Build = (SolutionBuild2)solution2.SolutionBuild;
            var projectNames = string.Empty;
            var allProjects = new List<Project>();
            foreach (Project project in solution2.Projects)
            {
                if (project.Kind.Equals(ProjectKinds.vsProjectKindSolutionFolder, StringComparison.InvariantCultureIgnoreCase))
                {
                    var solutionFolder = (SolutionFolder)project.Object;
                    foreach (ProjectItem projectItem in project.ProjectItems)
                    {
                        allProjects.Add(projectItem.SubProject);
                    }
                }
                else //if (project.Kind.Equals(ProjectType, StringComparison.InvariantCultureIgnoreCase))
                {
                    allProjects.Add(project);
                }
            }
            var allWebProjects = new List<ProjectModel>();
            foreach (var project in allProjects)
            {
                var projectOutputType = (int)project.Properties.Item("OutputType").Value;
                //if (projectOutputType == 2)
                    allWebProjects.Add(new ProjectModel(ServiceProvider, project));
            }
            return allWebProjects;
        }
        #endregion

    }
    public class ProjectModel
    {
        #region Ctor
        public ProjectModel(IServiceProvider serviceProvider, Project project)
        {
            Project = project;
            ServiceProvider = serviceProvider;
            PublishCommand = new DelegateCommand(OnPublish, CanPublish);
            BuildCommand = new DelegateCommand(OnBuild, CanBuild);
            ProjectSelector = new ProjectSelector(ServiceProvider);
            ConfigurePublishCommand = new DelegateCommand(OnConfigurePublish, CanConfigurePublish);
            PropertiesCommand = new DelegateCommand(OnProperties);
        }
        #endregion

        #region Properties
        public Project Project { get; set; }
        public IServiceProvider ServiceProvider { get; set; }
        protected ProjectSelector ProjectSelector { get; private set; }

        public string Name { get { return Project.Name; } }
        public string FullName { get { return Project.FullName; } }
        public int OutputType { get { return (int)Project.Properties.Item("OutputType").Value; } }
        public string Kind { get { return Project.Kind; } }
        #endregion

        #region Publish Command
        public ICommand PublishCommand { get; set; }
        public void OnPublish(object parameter)
        {
            try
            {
                var dte = Project.DTE;
                //var solutionBuild2 = (SolutionBuild2)dte.Solution.SolutionBuild;
                //solutionBuild2.PublishProject(Project.ConfigurationManager.ActiveConfiguration.ConfigurationName, Project.UniqueName, true);

                var solutionName = (string)dte.Solution.Properties.Item("Name").Value;
                dte.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate();
                var uiHierarchy = dte.ActiveWindow.Object as UIHierarchy;
                ProjectSelector.SelectProjectByName(Project.Name);
                
                var buildConfig = Project.ConfigurationManager.ActiveConfiguration.ConfigurationName;
                var publishProfile = "Profile1";
                dte.ExecuteCommand("Build.SolutionConfigurations", buildConfig);
                object customin = new object();
                object customout = new object();
                dte.Commands.Raise("{CB26E292-901A-419C-B79D-49BD45C43929}", 120, publishProfile, customout);
                dte.Commands.Raise("{CB26E292-901A-419C-B79D-49BD45C43929}", 122, customin, customout);
                dte.ExecuteCommand("ClassViewContextMenus.ClassViewProject.Publish");
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        public bool CanPublish(object parameter)
        {
            return Project.ConfigurationManager.ActiveConfiguration.IsRunable;
        }
        #endregion

        #region Configure Publish Command
        public ICommand ConfigurePublishCommand { get; set; }
        public void OnConfigurePublish(object parameter)
        {
            ExecuteCommand("ClassViewContextMenus.ClassViewProject.Publish");
        }
        public bool CanConfigurePublish(object parameter)
        {
            return Project.ConfigurationManager.ActiveConfiguration.IsRunable;
        }
        #endregion

        #region Build Command
        public ICommand BuildCommand { get; set; }
        public void OnBuild(object parameter)
        {
            try
            {
                if (Project != null)
                {
                    var dte = Project.DTE;
                    var solutionBuild2 = (SolutionBuild2)dte.Solution.SolutionBuild;
                    solutionBuild2.BuildProject(Project.ConfigurationManager.ActiveConfiguration.ConfigurationName, Project.UniqueName, true);
                }
                else
                {
                    MessageBox.Show("Project is NULL");
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        public bool CanBuild(object parameter)
        {
            return Project.ConfigurationManager.ActiveConfiguration.IsBuildable;
        }
        #endregion

        #region Properties Command
        public ICommand PropertiesCommand { get; set; }
        public void OnProperties(object parameter)
        {
            ExecuteCommand("Project.Properties");
        }
        #endregion

        #region Helper Methods
        private void ExecuteCommand(string commandName)
        {
            try
            {
                var dte = Project.DTE;
                var solutionName = (string)dte.Solution.Properties.Item("Name").Value;
                dte.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate();
                var uiHierarchy = dte.ActiveWindow.Object as UIHierarchy;
                ProjectSelector.SelectProjectByName(Project.Name);

                dte.ExecuteCommand(commandName);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        #endregion
    }

}